﻿ 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using NTTDATA.BEENChina.ResultCertification.DataStore;
using NTTDATA.BEENChina.ResultCertification.Result;
using NTTDATA.BEENChina.ResultCertification.model;
using Timer = System.Timers.Timer;

namespace NTTDATA.BEENChina.ResultCertification.Logic
{
    public class CheckMonitor
    {
        private Timer monitorTimer;
        private readonly object _lockobject = new object();
        private model.CheckSetting _checkCondition = null;



        public CheckMonitor()
        {
            monitorTimer = new Timer(10 * 1000);
            monitorTimer.Elapsed += new System.Timers.ElapsedEventHandler(MonitorTimerElapsed);
            monitorTimer.Stop();
        }

        private void LoadCheckCondition()
        {

            _checkCondition = new DataStore.CheckSettingAccess().GetCheckSetting();

        }


        private int ThreadNumber
        {
            get
            {
                //分成4份
                //同时检证
                int theradNumber = 0;
                string number = System.Configuration.ConfigurationManager.AppSettings["ThreadNumber"];



                //ActionMessage.GetInstance().onProcessMessage(string.Format("设定的线程数{0}", number), EnumProcessModel.取入数据);

                if (!int.TryParse(number, out theradNumber))
                {
                    theradNumber = 100;
                }

                if (theradNumber == 0)
                {
                    theradNumber = 100;
                }

                return theradNumber;
            }
        }

        public void Start()
        {
            monitorTimer.Start();
            WorkingState.GetInstance().Stop = false;

        }

        public void Stop()
        {
            
             monitorTimer.Stop();
            WorkingState.GetInstance().Stop = true;

        }

        public void LoadCheckCondition(CheckSetting checkCondition)
        {
            this._checkCondition = checkCondition;
        }

        private void MonitorTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Run();
        }

        private bool _isRunning;

   

        public void Run()
        {
            lock (_lockobject)
            {
                if (WorkingState.GetInstance().Stop)
                {
                
                    _isRunning = false;
                    return;
                }
                else 
                {
                    if (_isRunning   )
                    return;
                }





                ActionMessage.GetInstance().onProcessMessage("启动扫描 WorkingState is Running", EnumProcessModel.取入数据);

                LoadCheckCondition();


                if (_checkCondition != null 　&& 
                    !_checkCondition.BeginDeliveryTime.Equals(DateTime.MinValue) &&
                    !_checkCondition.EndDeliveryTime.Equals(DateTime.MinValue) &&
                    !_checkCondition.RunTime.Equals(DateTime.MinValue) 
                    )
                {
                    
                    DateTime checkRunTime = _checkCondition.RunTime;
                
                    if (DateTime.Compare(checkRunTime, DateTime.Now) < 0)
                    {
                        CheckSettingAccess checkSettingAccess = new CheckSettingAccess();
                    

                        //数据库判断去掉
                        /* _isRunning = checkSettingAccess.IsRunning(checkRunTime);
                         

                        if (_isRunning) 
                        {
                            // ActionMessage.GetInstance().onProcessMessage("已经执行",EnumProcessModel.取入数据);
                            return;
                        }
                        else
                        {
                            _isRunning = true;
                            // checkSettingAccess.AddRunningState(System.DateTime.Now); 
                        }*/

                        _isRunning = true;

                        ActionMessage.GetInstance().onProcessMessage(string.Format("开始 {0} - {1} -{2}",
                            _checkCondition.BeginDeliveryTime.ToString("yyyy-MM-dd HH:mm:ss"), _checkCondition.EndDeliveryTime.ToString("yyyy-MM-dd HH:mm:ss"), _checkCondition.RunTime), EnumProcessModel.取入数据);

                        int takeOrderCount = new DataTarget().GetOrders(EnumOrderState.受番取入).Count();

                        if (ProgramRunningState.GetInstance().OrderState == EnumOrderState.录入数据分析)
                        {
                        if (takeOrderCount>0)
                        {
                            ActionMessage.GetInstance().onProcessMessage("有未取入完成的受番", EnumProcessModel.取入数据);


                            AnalysisResult();
                        }
                        }


                        if ((ProgramRunningState.GetInstance().OrderState == EnumOrderState.受番取入)
                            ||
                            (ProgramRunningState.GetInstance().OrderState == EnumOrderState.录入数据分析 &&
                             takeOrderCount == 0))
                      
                        {
                            //删除 
                            //new DataStore.DataTarget().RemoveOrders();
                            
                             ProgramRunningState.GetInstance().SaveState(EnumOrderState.受番取入);

                            ActionMessage.GetInstance().onProcessMessage("开始新的数据取入", EnumProcessModel.取入数据);

                            CheckOrders checkOrders = new CheckOrders(_checkCondition);
                            checkOrders.AllOrdersComplete +=
                                new EventHandler<CheckOrdersEventArgs>(CheckOrdersAllOrdersComplete);
                            //checkOrders.EachOrderComplete -= new EventHandler<CheckOrdersEventArgs>(checkOrders_EachOrderComplete);
                            //checkOrders.EachOrderComplete += new EventHandler<CheckOrdersEventArgs>(checkOrders_EachOrderComplete);

                            ActionMessage.GetInstance().onProcessMessage("获得全部的已完成的受番ID-开始", EnumProcessModel.取入数据);

                            checkOrders.GetCompleteOrder();
                        }
                    }
                    else
                    {
                     
                        ActionMessage.GetInstance().onProcessMessage(string.Format("未到启动时间 {0} - {1} -{2}",
                            _checkCondition.BeginDeliveryTime.ToString("yyyy-MM-dd HH:mm:ss"), _checkCondition.EndDeliveryTime.ToString("yyyy-MM-dd HH:mm:ss"), _checkCondition.RunTime), EnumProcessModel.取入数据);
                    }
                }
                else
                {
                    ActionMessage.GetInstance().onProcessMessage( "没有未完成的任务" , EnumProcessModel.取入数据);
                }
            }
        }

        /// <summary>
        /// 受番ID保留完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CheckOrdersAllOrdersComplete(object sender, CheckOrdersEventArgs e)
        {
            ActionMessage.GetInstance().onProcessMessage("获得全部的已完成的受番ID-完了", EnumProcessModel.取入数据);

            ProgramRunningState.GetInstance().SaveState(EnumOrderState.录入数据分析);
     
           
           AnalysisResult(); 
    
        }

        /// <summary>
        /// 分析结果
        /// </summary>
        private void AnalysisResult()
        {

            ActionMessage.GetInstance().onProcessMessage("获得录入结果    开始", EnumProcessModel.取入数据);

            IEnumerable<OrderData> orderDatas = new DataTarget().GetOrders(EnumOrderState.受番取入);

            //本时间段没有 受番
            if (orderDatas.Count().Equals(0))
            {
                //本次结束
                VerfityFinish();
            }

            _checkEntryResult.CheckCategorys = this._checkCondition.VerifyCategorys;



            int splitNumber = 1;

     

#if !DEBUG
            splitNumber = WorkingState.GetInstance().SplitNumber;       
#endif

            var orderDatasCollection = Util.SplitList.Split(orderDatas.ToList(), splitNumber);

            for (int i = 0; i < orderDatasCollection.Count; i++)
            {
                var item = orderDatasCollection[i];
                string threadName = string.Format("Analy{0}", i);

#if !DEBUG                
                var threadGetResult = new Thread(() => GetEntryResult(item,threadName)) { Name = threadName };
                threadGetResult.Start();
#else
                GetEntryResult(item, threadName);
#endif
            }
        }



        readonly CheckEntryResult _checkEntryResult = new CheckEntryResult();

        private void GetEntryResult(List<OrderData> orderDatas,string threadName)
        {
          
            IDataTarget dataTarget = new DataTarget();   

            int count = 0;
            if (orderDatas != null)
            {
                foreach (OrderData orderData in orderDatas )
                {
                    top:

                    int currentProcessCount = Process.GetCurrentProcess().Threads.Count;

                    if (currentProcessCount >= ThreadNumber)
                    {
                        Thread.Sleep(1000 * 60);
                        goto top;
                    }

                    count++;

                    try
                    {

                        ActionMessage.GetInstance().onProcessMessage(
                            string.Format("{0} 处理中  Part{2} :剩余 {1}", orderData.OrderId, orderDatas.Count() - count,threadName),
                            EnumProcessModel.取入数据);


                        //ActionMessage.GetInstance().onProcessMessage("获得录入结果", EnumProcessModel.取入数据);
                        ////根据 需要验证的categorys 得到录入结果
                        //List<ChildImage> childImages = checkEntryResult.GetEntryResult(orderData.ServerCode, orderData.OrderId, true);


                       /* ActionMessage.GetInstance().onProcessMessage("分析结果", EnumProcessModel.取入数据);
                        //执行检查
                        VerfityEntryResult(childImages);*/ 
                        
                        OrderData data = orderData;
                        List<ChildImage> childImages = null;

#if !DEBUG

                        var threadGetResult = new Thread(() =>
                                    {
#endif
                                        try
                                        {
                                            ActionMessage.GetInstance().onProcessMessage(string.Format("{0} 获得录入结果",data.OrderId), EnumProcessModel.取入数据);
                                            //根据 需要验证的categorys 得到录入结果
                                            childImages =_checkEntryResult.GetEntryResult(data.ServerCode,data.OrderId, true);
                                        }
                                        catch (Exception ex)
                                        {
                                            Log.Console.Error(string.Format("CheckMonitor GetEntryResult GetError orid {0}", data.OrderId), ex);
                                        }


                                        //ActionMessage.GetInstance().onProcessMessage("获得录入结果 ok", EnumProcessModel.取入数据);
#if !DEBUG
                                    }) {Name = "g"+data.OrderId};
                        threadGetResult.Start();
                        threadGetResult.Join(new TimeSpan(0, 5, 0));
                        threadGetResult.Abort();
#endif

                        //判断停止标记
                        if (WorkingState.GetInstance().Stop)
                        {
                            ActionMessage.GetInstance().onProcessMessage("用户终止", EnumProcessModel.取入数据);
                            break;

                        }
#if !DEBUG
                        var threadVerfity = new Thread(() =>
                            {
#endif
                                try
                                {
                                    ActionMessage.GetInstance().onProcessMessage(string.Format("{0} 分析结果",data.OrderId),EnumProcessModel.取入数据);

                                    //受番是否存在分析结果
                                    if (dataTarget.ExistChildImages(data.OrderId))
                                    {
                                       // 删除受番对应的画像，避免重复插入
                                        dataTarget.DeleteChildImages(data.OrderId);
                                    }
 
                                    //执行检查
                                    VerfityEntryResult(childImages);
                                    ActionMessage.GetInstance().onProcessMessage(string.Format("{0} 更新状态", data.OrderId), EnumProcessModel.取入数据);

                                    dataTarget.UpdateOrderStates(data.ServerCode,data.OrderId,EnumOrderState.录入数据分析);

                                    //是否还有要处理的受番，如果没有 标记结束
                                    if (!WorkingState.GetInstance().Stop)
                                        VerfityFinish();
                                }
                                catch (Exception ex)
                                {
                                    Log.Console.Error(string.Format("CheckMonitor GetEntryResult VerfityError orid {0}", data.OrderId ), ex);
                                    
                                }
#if !DEBUG                          
                            }) {Name = "v"+orderData.OrderId};

                        threadVerfity.Start();  
#endif
                        /*ActionMessage.GetInstance().onProcessMessage("更新状态", EnumProcessModel.取入数据);
                         * 
                        dataTarget.UpdateOrderStates(orderData.ServerCode, orderData.OrderId, EnumOrderState.录入数据分析);*/

                        
                        /*   ActionMessage.GetInstance().onProcessMessage(
                               string.Format("获得受番对应的录入结果-第{0}条完了 ", count),
                               EnumProcessModel.取入数据);*/

                    }
                    catch (Exception ex)
                    {
                        Log.Console.Error("CheckMonitor GetEntryResult", ex);
                    }
                }
            }

           

        
        }

        private void VerfityFinish()
        {
            int takeOrderCount = new DataTarget().GetOrders(EnumOrderState.受番取入).Count();

            if (takeOrderCount == 0)
            {
                //new CheckSettingAccess().AddRunningState(System.DateTime.Now);

                _checkCondition.RunFlag = 1;
                new CheckSettingAccess().UpdateRunningFlag(_checkCondition);

                this._isRunning = false;

                ActionMessage.GetInstance().onProcessMessage("获得录入结果    结束", EnumProcessModel.取入数据);


            }
        }


       /* private void VerfityEntryResultAndUpdate(OrderData orderData, IEnumerable<ChildImage> childImages)
        {
            VerfityEntryResult(childImages);

            IDataTarget dataTarget = new DataTarget();
            dataTarget.UpdateOrderStates(orderData.ServerCode, orderData.OrderId, EnumOrderState.录入数据分析);

            ActionMessage.GetInstance().onProcessMessage("更新状态", EnumProcessModel.取入数据);
        }*/

        private void VerfityEntryResult( IEnumerable<ChildImage> childImages)
        {
            IDataTarget dataTarget = new DataTarget();
            IDataSource dataSource = new DataSource();



            // ActionMessage.GetInstance().onProcessMessage("分析结果-开始" ,EnumProcessModel.取入数据);

            if (childImages != null)
            {
               // int count = childImages.Count() -1;


                var dicForm = new Dictionary<string, string>();
                var dicCategroy = new Dictionary<string, string>();
                

                foreach (var childImage in childImages)
                {
                   

                    bool verfityResult = childImage.Verfity();

                    //分析结果 详细日志 输出
                   // ActionMessage.GetInstance().onProcessMessage(string.Format(" imageid {0} {1}  剩余{2}条", childImage.ImageId, !verfityResult?"○":"×"  ,count--), EnumProcessModel.取入数据);

                    if (verfityResult)
                    {
                        //补充 formName categoryName OpId
                        //去掉补充opid的逻辑
                        //增加速度
                        //var  childImageA = dataSource.CompleteNameAndOpId(childImage);

                        //find From Dic
 

                        if (dicForm.ContainsKey(childImage.FormId))
                        {
                            childImage.FormName = dicForm.Single(t => t.Key.Equals(childImage.FormId)).Value;
                        }
                        else
                        {
                            string formName = dataSource.GetFromName(childImage.FormId, childImage.CustomerId);

                            childImage.FormName = formName;

                            dicForm.Add(childImage.FormId,formName);
                        }


                        if (dicCategroy.ContainsKey(childImage.CategoryId))
                        {
                            childImage.CategoryName = dicCategroy.Single(t => t.Key.Equals(childImage.CategoryId)).Value;
                        }
                        else
                        {
                            string categoryName = dataSource.GetCategoryName(childImage.CategoryId);

                            childImage.CategoryName = categoryName;

                            dicCategroy.Add(childImage.CategoryId,categoryName);
                        }

                        //save to db
                        //ActionMessage.GetInstance().onProcessMessage("分析结果-存入DB", EnumProcessModel.取入数据);
                        dataTarget.InsertChildImage(childImage);

                    }  

                }
            }

         // ActionMessage.GetInstance().onProcessMessage("分析结果-结束", EnumProcessModel.取入数据);
        }

    }
}
